package gew.services;

import gew.beans.DataFacade2;
import gew.metadata.CustomSql;
import gew.system.Constants;
import gew.system.Labels;
import gew.system.RequestParameter;
import gew.utils.SqlUtils;
import gew.data.MenuItem;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.ejb.Stateless;

@Stateless
public class MainMenuService {

    @EJB
    private DataFacade2 dataFacade2;

    private static final MenuItem DEFAULT_MENU_ITEM = new MenuItem("NO SUCH ITEM", "");
    private static final ArrayList<MenuItem> DEFAULT_MENU_ITEMS;
    
    private final HashMap<Locale, HashMap<MenuItem, List<MenuItem>>> tradeMenuItems = new HashMap();
    private final HashMap<Locale, ArrayList<MenuItem>> tradeMenuGroups = new HashMap();
    private final HashMap<Locale, String> tradeMenuHeaders = new HashMap();
    private final HashMap<Locale, String> tradeMenuHeaderUrls = new HashMap();
    
    private final HashMap<Locale, HashMap<MenuItem, List<MenuItem>>> indicatorsMenuItems = new HashMap();
    private final HashMap<Locale, ArrayList<MenuItem>> indicatorsMenuGroups = new HashMap();
    private final HashMap<Locale, String> indicatorsMenuHeaders = new HashMap();
    private final HashMap<Locale, String> indicatorsMenuHeaderUrls = new HashMap();
    
    private final HashMap<Locale, HashMap<MenuItem, List<MenuItem>>> industriesMenuItems = new HashMap();
    private final HashMap<Locale, ArrayList<MenuItem>> industriesMenuGroups = new HashMap();
    private final HashMap<Locale, String> industriesMenuHeaders = new HashMap();
    private final HashMap<Locale, String> industriesMenuHeaderUrls = new HashMap();
    
    static {
        DEFAULT_MENU_ITEMS = new ArrayList<>();
        DEFAULT_MENU_ITEMS.add(DEFAULT_MENU_ITEM);
    }

    @PostConstruct
    public void init() {
        initTradeMenu(LocaleService.getLocaleEN());
        initTradeMenu(LocaleService.getLocaleRU());
        initIndicatorsMenu(LocaleService.getLocaleEN());
        initIndicatorsMenu(LocaleService.getLocaleRU());
        initIndustriesMenu(LocaleService.getLocaleEN());
        initIndustriesMenu(LocaleService.getLocaleRU());
    }    
    
    private void initIndustriesMenu(Locale locale) {
        String q1 = CustomSql.getMenuIndustries(locale);
        List<MenuItem> list = dataFacade2.getMenuItems(q1);
        if (list == null) {
            return;
        }
        industriesMenuItems.put(locale, new HashMap<>());
        industriesMenuGroups.put(locale, new ArrayList<>());
        MenuItem currGroup = null;
        for (int i = 0; i < list.size(); i++) {
            MenuItem menuItem = list.get(i);
            if (menuItem.getAggregateLevel() == 0) {
                industriesMenuItems.get(locale).put(menuItem, new ArrayList<>());
                industriesMenuGroups.get(locale).add(menuItem);
                currGroup = menuItem;
            } else {
                if (currGroup != null) {
                    industriesMenuItems.get(locale).get(currGroup).add(menuItem);
                }
            }
        }

        for (int i = 0; i < industriesMenuGroups.get(locale).size(); i++) {
            MenuItem groupItem = industriesMenuGroups.get(locale).get(i);
            for (int j = 0; j < industriesMenuItems.get(locale).get(groupItem).size(); j++) {
                String urlCode = industriesMenuItems.get(locale).get(groupItem).get(j).getUrlCode();
                String url = getIndustriesUrl(locale, urlCode, Labels.get_PARAM_DEFAULT_COUNTRY_CODE_VALUE(locale));
                industriesMenuItems.get(locale).get(groupItem).get(j).setUrl(url);
                if (j == 0) {
                    groupItem.setUrl(url);
                    if (i == 0) {
                        industriesMenuHeaderUrls.put(locale, url);
                    }
                }
            }
            MenuItem moreMenuItem = new MenuItem(Labels.get_MENU_MORE_INDICATORS(locale), "#", true);
            moreMenuItem.setUrl(groupItem.getUrl());
            industriesMenuItems.get(locale).get(industriesMenuGroups.get(locale).get(i)).add(moreMenuItem);
        }
        industriesMenuHeaders.put(locale, Labels.get_UI_MENU_INDUSTRIES_HEADER(locale));
    }

    public String getIndustriesHeader(Locale locale) {
        return industriesMenuHeaders.get(locale);
    }

    public String getIndustriesHeaderUrl(Locale locale) {
        return industriesMenuHeaderUrls.get(locale);
    }

    public MenuItem getIndustriesGroupMenuItem(Locale locale, int index) {
        if (industriesMenuGroups.containsKey(locale) && industriesMenuGroups.get(locale).size() > index) {
            return industriesMenuGroups.get(locale).get(index);
        } else {
            return DEFAULT_MENU_ITEM;
        }
    }
    
    public ArrayList<MenuItem> getIndustriesGroupMenuItems(Locale locale) {
        if (industriesMenuGroups.containsKey(locale)) {
            return industriesMenuGroups.get(locale);
        } else {
            return DEFAULT_MENU_ITEMS;
        }
    }

    public List<MenuItem> getIndustriesMenuItems(Locale locale, int index) {
        if (industriesMenuItems.containsKey(locale) && industriesMenuGroups.get(locale).size() > index) {
            return industriesMenuItems.get(locale).get(industriesMenuGroups.get(locale).get(index));
        } else {
            return new ArrayList<>();
        }
    }

    private void initIndicatorsMenu(Locale locale) {
        String q1 = CustomSql.getMenuIndicators(locale);
        List<MenuItem> list = dataFacade2.getMenuItems(q1);
        if (list == null) {
            return;
        }
        indicatorsMenuItems.put(locale, new HashMap<>());
        indicatorsMenuGroups.put(locale, new ArrayList<>());
        MenuItem currGroup = null;
        for (int i = 0; i < list.size(); i++) {
            MenuItem menuItem = list.get(i);
            if (menuItem.getAggregateLevel() == 0) {
                indicatorsMenuItems.get(locale).put(menuItem, new ArrayList<>());
                indicatorsMenuGroups.get(locale).add(menuItem);
                currGroup = menuItem;
            } else {
                if (currGroup != null) {
                    indicatorsMenuItems.get(locale).get(currGroup).add(menuItem);
                }
            }
        }

        for (int i = 0; i < indicatorsMenuGroups.get(locale).size(); i++) {
            MenuItem groupItem = indicatorsMenuGroups.get(locale).get(i);
            for (int j = 0; j < indicatorsMenuItems.get(locale).get(groupItem).size(); j++) {
                String urlCode = indicatorsMenuItems.get(locale).get(groupItem).get(j).getUrlCode();
                String url = getIndicatorsUrl(locale, urlCode, Labels.get_PARAM_DEFAULT_COUNTRY_CODE_VALUE(locale));
                indicatorsMenuItems.get(locale).get(groupItem).get(j).setUrl(url);
                if (j == 0) {
                    groupItem.setUrl(url);
                    if (i == 0) {
                        indicatorsMenuHeaderUrls.put(locale, url);
                    }
                }
            }
            MenuItem moreMenuItem = new MenuItem(Labels.get_MENU_MORE_INDICATORS(locale), "#", true);
            moreMenuItem.setUrl(groupItem.getUrl());
            indicatorsMenuItems.get(locale).get(indicatorsMenuGroups.get(locale).get(i)).add(moreMenuItem);
        }
        indicatorsMenuHeaders.put(locale, Labels.get_UI_MENU_INDICATORS_HEADER(locale));
    }

    public String getIndicatorsHeader(Locale locale) {
        return indicatorsMenuHeaders.get(locale);
    }

    public String getIndicatorsHeaderUrl(Locale locale) {
        return indicatorsMenuHeaderUrls.get(locale);
    }

    public MenuItem getIndicatorsGroupMenuItem(Locale locale, int index) {
        if (indicatorsMenuGroups.containsKey(locale) && indicatorsMenuGroups.get(locale).size() > index) {
            return indicatorsMenuGroups.get(locale).get(index);
        } else {
            return DEFAULT_MENU_ITEM;
        }
    }
    
    public ArrayList<MenuItem> getIndicatorsGroupMenuItems(Locale locale) {
        if (indicatorsMenuGroups.containsKey(locale)) {
            return indicatorsMenuGroups.get(locale);
        } else {
            return DEFAULT_MENU_ITEMS;
        }
    }

    public List<MenuItem> getIndicatorsMenuItems(Locale locale, int index) {
        if (indicatorsMenuItems.containsKey(locale) && indicatorsMenuGroups.get(locale).size() > index) {
            return indicatorsMenuItems.get(locale).get(indicatorsMenuGroups.get(locale).get(index));
        } else {
            return new ArrayList<>();
        }
    }

    private void initTradeMenu(Locale locale) {
        String q1 = CustomSql.getMenuTrade(locale);
        List<MenuItem> list = dataFacade2.getMenuItems(q1);
        if (list == null) {
            return;
        }
        tradeMenuItems.put(locale, new HashMap<>());
        tradeMenuGroups.put(locale, new ArrayList<>());
        MenuItem currGroup = null;
        for (int i = 0; i < list.size(); i++) {
            MenuItem menuItem = list.get(i);
            if (menuItem.getAggregateLevel() == 0) {
                tradeMenuItems.get(locale).put(menuItem, new ArrayList<>());
                tradeMenuGroups.get(locale).add(menuItem);
                currGroup = menuItem;
            } else {
                if (currGroup != null) {
                    tradeMenuItems.get(locale).get(currGroup).add(menuItem);
                }
            }
        }
        String commodityGroupTypeUrl = Labels.get_PARAM_DEFAULT_COMMODITY_GROUP_TYPE_CODE_VALUE(locale);
        ArrayList<String> urls = new ArrayList<>();
        for (int i = 0; i < tradeMenuGroups.get(locale).size(); i++) {
            MenuItem groupItem = tradeMenuGroups.get(locale).get(i);
            urls.add(groupItem.getUrlCode());
            ArrayList<String> groupUrls = new ArrayList<>();
            groupUrls.add(groupItem.getUrlCode());
            for (int j = 0; j < tradeMenuItems.get(locale).get(groupItem).size(); j++) {
                String urlCode = tradeMenuItems.get(locale).get(groupItem).get(j).getUrlCode();
                String[] urlCodes = new String[]{groupItem.getUrlCode(), urlCode};
                Arrays.sort(urlCodes);
                tradeMenuItems.get(locale).get(groupItem).get(j)
                        .setUrl(getTradeSummaryUrl(locale, String.join(SqlUtils.HYPHEN, urlCodes), commodityGroupTypeUrl, urlCode));
                groupUrls.add(urlCode);
            }
            groupUrls.sort(null);
            groupItem.setUrl(getTradeSummaryUrl(locale, String.join(SqlUtils.HYPHEN, groupUrls), commodityGroupTypeUrl, groupItem.getUrlCode()));
            MenuItem moreMenuItem = new MenuItem(Labels.get_MENU_MORE_COUNTRIES(locale), "#", true);
            moreMenuItem.setUrl(getTradeSummaryUrl(locale, String.join(SqlUtils.HYPHEN, groupUrls), commodityGroupTypeUrl, groupItem.getUrlCode()));
            tradeMenuItems.get(locale).get(tradeMenuGroups.get(locale).get(i)).add(moreMenuItem);
        }

        tradeMenuHeaders.put(locale, Labels.get_UI_MENU_TRADE_HEADER(locale));
        urls.sort(
                null);
        tradeMenuHeaderUrls.put(locale, getTradeSummaryUrl(locale, String.join(SqlUtils.HYPHEN, urls), commodityGroupTypeUrl, SqlUtils.EMPTY));
    }

    public String getTradeHeader(Locale locale) {
        return tradeMenuHeaders.get(locale);
    }

    public String getTradeHeaderUrl(Locale locale) {
        return tradeMenuHeaderUrls.get(locale);
    }

    public MenuItem getTradeGroupMenuItem(Locale locale, int index) {
        if (tradeMenuGroups.containsKey(locale) && tradeMenuGroups.get(locale).size() > index) {
            return tradeMenuGroups.get(locale).get(index);
        } else {
            return DEFAULT_MENU_ITEM;
        }
    }
    
    public ArrayList<MenuItem> getTradeGroupMenuItems(Locale locale) {
        if (tradeMenuGroups.containsKey(locale)) {
            return tradeMenuGroups.get(locale);
        } else {
            return DEFAULT_MENU_ITEMS;
        }
    }

    public List<MenuItem> getTradeMenuItems(Locale locale, int index) {
        if (tradeMenuItems.containsKey(locale) && tradeMenuGroups.get(locale).size() > index) {
            return tradeMenuItems.get(locale).get(tradeMenuGroups.get(locale).get(index));
        } else {
            return new ArrayList<>();
        }
    }   

    private String getTradeSummaryUrl(Locale locale, String reporterUrl, String commodityGroupTypeUrl, String bookmark) {
        StringBuilder buf = new StringBuilder();
        buf
                .append(SqlUtils.SLASH)
                .append(locale.getLanguage())
                .append(SqlUtils.SLASH)
                .append(Constants.SECTION_TRADE_SUMMARY)
                .append(SqlUtils.SLASH)
                .append(commodityGroupTypeUrl)
                .append(SqlUtils.SLASH)
                .append(reporterUrl)
                .append(SqlUtils.OCTOTHORPE)
                .append(bookmark);
        return buf.toString();
    }

    private String getIndicatorsUrl(Locale locale, String indicatorUrlCode, String countryCode) {
        StringBuilder buf = new StringBuilder();
        buf
                .append(SqlUtils.SLASH)
                .append(locale.getLanguage())
                .append(SqlUtils.SLASH)
                .append(Constants.SECTION_INDICATORS)
                .append(SqlUtils.SLASH)
                .append(indicatorUrlCode)
                .append(SqlUtils.SLASH)
                .append(countryCode);
        return buf.toString();
    }
    
    private String getIndustriesUrl(Locale locale, String indicatorUrlCode, String countryCode) {
        StringBuilder buf = new StringBuilder();
        buf
                .append(SqlUtils.SLASH)
                .append(locale.getLanguage())
                .append(SqlUtils.SLASH)
                .append(Constants.SECTION_INDUSTRIES)
                .append(SqlUtils.SLASH)
                .append(indicatorUrlCode)
                .append(SqlUtils.SLASH)
                .append(countryCode);
        return buf.toString();
    }

    public String getUrlHomePage(RequestParameter rp) {
        StringBuilder buf = new StringBuilder();
        buf
                .append(SqlUtils.SLASH)
                .append(rp.getLocaleUrlCode())
                .append(SqlUtils.SLASH)
                .append(Constants.SECTION_HOME);
        return buf.toString();
    }
}
